package mathy.wili.extract_srcFile.java;
import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import mathy.c.LogConf;
import mathy.wili.c.Class9;
import mathy.wili.c.File9;
import mathy.wili.c.File9.TranverseFun;
import mathy.wili.c.Str9;
import mathy.wili.c.asm.Asm9;
/**
 * 	用来搜集并判断：属性是否静态常量简单值。
 * @author weila 2021年3月1日
 */
public class StaticFinalSimpleValue_fieldCheck implements Serializable {
	private static final long serialVersionUID = 1L;

	final Map<Class<?>, Set<String>> clsToConstFieldsMap = new HashMap<>();

	final int constFieldNum;

	static StaticFinalSimpleValue_fieldCheck INST;
	public String toString() {
		return "clsNum:" + clsToConstFieldsMap.size() + ", constFieldNum:" + constFieldNum;
	}

	private StaticFinalSimpleValue_fieldCheck(File... srcRoots) {
		File clsRoot = null;
		if ("".isEmpty() || srcRoots == null || srcRoots.length == 0) {
			clsRoot = Class9.jarFileOrClassRootOf(StaticFinalSimpleValue_fieldCheck.class);
		}
		int[] nums = { 0 };
		String rootPath = clsRoot.getAbsolutePath().replace(File.separatorChar, '.');
		File9.traverseFile(clsRoot, 0, new TranverseFun() {
			@Override
			public void doFun(int depth, File file) {
				if (!file.getName().endsWith(".class"))
					return;
				String fname = file.getName();
				int ind = fname.lastIndexOf('$');
				if (ind != -1 && Str9.isNumChar(fname, ind + 1))
					return;//本地类
				String pkgNam = Class9.packageNameOfClassFile(rootPath, file);
				//				String pkgNam = file.getAbsolutePath();
				//				pkgNam = pkgNam.substring(0, pkgNam.lastIndexOf(File.separatorChar));
				//				pkgNam = pkgNam.replace(File.separatorChar, '.');
				//				pkgNam = pkgNam.substring(rootPath.length() + 1);
				Class<?> cls = Class9.classOfClassFile(pkgNam, file);
				if ("".isEmpty()) {
					Asm9.removeFinalModifier_fromStaticFinalSimpleFields__(cls, file);
					return;
				}
				if (cls == null)
					return;
				if (cls.isAnonymousClass() || cls.isSynthetic() || cls.isAnnotation() || cls.isLocalClass())
					return;
				Set<String> set = null;
				Field[] ff = cls.getDeclaredFields();
				//ff.toString();
				for (Field field : ff) {
					if (Class9.isStaticFinalSimpleValue(cls, field)) {
						if (set == null)
							set = new HashSet<>();
						set.add(field.getName());
						++nums[0];
					}
				}
				if (set == null)
					return;
				++nums[0];
				clsToConstFieldsMap.put(cls, set);
			}
		});
		this.constFieldNum = nums[0];
	}

	/**
	 *   
	 */
	@Deprecated //2021-03-02
	public static StaticFinalSimpleValue_fieldCheck getInst__(boolean refresh, File... srcRoots) {
		if ("".isEmpty())
			return null;
		if (refresh || INST == null) {
			File file = new File(LogConf.ConfRoot, StaticFinalSimpleValue_fieldCheck.class.getSimpleName());
			if (!refresh && file.exists()) {
				INST = File9.readObject(file);
			} else {
				INST = new StaticFinalSimpleValue_fieldCheck(srcRoots);
				File9.writeObject(INST, file, -1);
			}
		}
		return INST;
	}
}